﻿#region

using System.Text.RegularExpressions;
using Vin.Tool.Core.AssertCategory;
using Vin.Tool.Core.JsonCategory;
using Vin.Tool.Enums;

#endregion

namespace Vin.Tool.Core.BasicTypeCategory;

public static partial class Extension
{
    #region 字符串转换

    public static string ToCovert(this string? str, ConvertOptionType optionType)
    {
        str = optionType switch
        {
            ConvertOptionType.CamelCase => str.ToCamelCase(),
            ConvertOptionType.UnderLineLower => str.ToUnderLine(),
            ConvertOptionType.UnderLineUpper => str.ToUnderLine(true),
            ConvertOptionType.MiddleLineLower => str.ToMiddleLine(),
            ConvertOptionType.MiddleLineUpper => str.ToMiddleLine(true),
            _ => str
        };
        return str ?? "";
    }

    public static string? ToUnderLine(this string? str, bool isToUpper = false)
    {
        if (str.IsNullOrEmpty() || str!.Contains('_'))
            return str;
        var result = string.Concat(str.Select((item, index) =>
            index <= 0 || !char.IsUpper(item) ? item.ToString() : "_" + item));
        return isToUpper ? result.ToUpper() : result.ToLower();
    }

    public static string? ToMiddleLine(this string? str, bool isToUpper = false)
    {
        if (str.IsNullOrEmpty() || str!.Contains('-'))
            return str;
        var result = string.Concat(str.Select((item, index) =>
            index <= 0 || !char.IsUpper(item) ? item.ToString() : "-" + item));
        return isToUpper ? result.ToUpper() : result.ToLower();
    }

    /// <summary>
    /// 字符串转换为驼峰命名
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string? ToCamelCase(this string? str, bool isToUpper = false)
    {
        if (str.IsNullOrEmpty()) return str;
        return (isToUpper ? str!.FirstOrDefault().ToString().ToUpper() : str!.FirstOrDefault().ToString().ToLower()) +
               str!.Substring(1);
    }

    public static string? ToCamelCase(this string? str, string separator, bool isToUpper = false)
    {
        if (str.IsNullOrEmpty()) return str;
        return string.Join(separator, str!.Split(separator).Select(item => item.ToCamelCase(isToUpper)));
    }

    #endregion

    #region 获取字符串

    /// <summary>
    /// 从字符串的末尾获取指定长度的字符串
    /// </summary>
    /// <param name="str"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    public static string? LatterString(this string? str, int count)
    {
        if (str.IsNullOrEmpty() || str?.Length <= count) return str;
        return str?.Substring(str.Length - count);
    }

    #endregion

    #region 格式化

    /// <summary>
    /// 格式化
    /// </summary>
    /// <param name="input"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public static string Format(this string? input, List<object> args)
    {
        if (string.IsNullOrEmpty(input)) return input ?? string.Empty;

        for (int i = 0; i < args.Count; i++)
        {
            input = input.Replace("{" + i + "}", args[i].ToString());
        }

        return input;
    }

    public static string Format(this string? input, params object[] args)
    {
        if (string.IsNullOrEmpty(input)) return input ?? string.Empty;
        return string.Format(input, args);
    }

    public static string Format(this string? input, string args)
    {
        if (string.IsNullOrEmpty(input)) return input ?? string.Empty;
        return string.Format(input, args);
    }

    public static string Format(this string? input, object? arg)
    {
        if (string.IsNullOrEmpty(input) || arg == null) return input ?? string.Empty;

        var match = Regex.Matches(input, @"\{(.+?)\}");
        foreach (Match item in match)
        {
            var value = arg.GetNestedArrayValue(item.Groups[1].Value);
            if (value != null)
            {
                input = input.Replace(item.Value, value.ToString());
            }
        }
        // var properties = arg.GetType().GetProperties();
        // foreach (var property in properties)
        // {
        //     var value = property.GetValue(arg);
        //     if (value != null)
        //     {
        //         input = input.Replace("{" + property.Name + "}", value.ToString());
        //     }
        // }

        return input;
    }

    public static string Format(this string? input, Dictionary<string, object>? arg)
    {
        if (string.IsNullOrEmpty(input) || arg == null) return input ?? string.Empty;

        foreach (var item in arg)
        {
            input = input.Replace("{" + item.Key + "}", item.Value.ToString());
        }

        return input;
    }

    #endregion

    #region Base64

    public static bool IsBase64(this string? str)
    {
        if (str.IsNullOrEmpty()) return false;
        return str!.Length % 4 == 0 && Regex.IsMatch(str, @"^[A-Za-z0-9\+\/\=]+$", RegexOptions.None);
    }

    public static bool IsBase64ByTry(this string? str)
    {
        if (str.IsNullOrEmpty()) return false;
        try
        {
            var _ = Convert.FromBase64String(str!);
            return true;
        }
        catch
        {
            return false;
        }
    }

    #endregion

    #region 转日期

    public static DateTime? ToDateTime(this string? str)
    {
        if (str.IsNullOrEmpty()) return null;
        return DateTime.TryParse(str, out var result) ? result : null;
    }

    #endregion

    #region 字符串三元

    public static string IfNull(this string? str, string defaultValue)
    {
        return str.IsNotNullOrWhiteSpace() ? str! : defaultValue;
    }

    #endregion

    #region 超出字符隐藏用其他字符代替

    public static string OverflowReplace(this string? str, int maxLength, string replace = "...")
    {
        if (str.IsNullOrEmpty() || str!.Length <= maxLength) return str ?? string.Empty;
        return str.Substring(0, maxLength) + replace;
    }

    #endregion

    #region 是否是URL

    /// <summary>
    /// 判断字符串是否是URL
    /// </summary>
    public static bool IsUrl(this string? str)
    {
        if (str.IsNullOrEmpty()) return false;
        var regex = new Regex(@"^(http|https)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$");
        return regex.IsMatch(str!);
    }

    #endregion
}